/**  
 * @Title: MybatisC.java
 * @Description: TODO(描述)
 * @author liuyi
 * @date 2023-07-24 14:29:23 
 */  
package com.fsxgt.datagrid.ds.component;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;

import javax.sql.DataSource;

import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMap;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.fsxgt.datagrid.ds.exception.DsException;

@Component
public class MybatisComponent {

	@Autowired
	private QueryComponent queryComponent;
	
	private SqlSessionFactory getSqlSessionFactory(Long dataSourceId) throws  DsException {

		DataSource  dataSource=queryComponent.getHandler(dataSourceId).getDatasource();
		// 采用 MyBatis 的 JDBC 事务方式
		TransactionFactory transactionFactory = new JdbcTransactionFactory();
		Environment environment = new Environment ("development", transactionFactory, dataSource);
		// 创建 Configuration 对象
		Configuration configuration = new Configuration(environment);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
		
		return sqlSessionFactory;
	}
	
	public Integer insert(Long dataSourceId,String sql,Map params) throws  DsException {
		
		SqlSessionFactory sqlSessionFactory = getSqlSessionFactory(dataSourceId);
		
		Configuration configuration = sqlSessionFactory.getConfiguration();
		
        //xml解析驱动
        final XMLLanguageDriver languageDriver = new XMLLanguageDriver();
        
        SqlSource sqlSource = languageDriver.createSqlSource(configuration,
                "<script>" + sql + "</script>", null);
        
        MappedStatement.Builder mapper = new MappedStatement.Builder(configuration, 
        		"insert", sqlSource, SqlCommandType.INSERT);
        
        ResultMap.Builder builder1 = new ResultMap.Builder(configuration, "insert.resultMap", Integer.class, new ArrayList<>());
        mapper.resultMaps(Collections.singletonList(builder1.build()));
        
        ParameterMap.Builder builder2 = new ParameterMap.Builder(configuration,  "insert.param", HashMap.class, new ArrayList<>());
        mapper.parameterMap(builder2.build());
        configuration.addMappedStatement(mapper.build());
        
       
        SqlSession sqlSession = null;
        try{
			sqlSession = sqlSessionFactory.openSession(true);
			return sqlSession.update("insert", params);
        }finally{
        	if(sqlSession!=null) {
        		sqlSession.close();
        	}
        }
	}
	
	public Integer update(Long dataSourceId,String sql,Map params) throws  DsException {
		
		
		SqlSessionFactory sqlSessionFactory = getSqlSessionFactory(dataSourceId);
		
		Configuration configuration = sqlSessionFactory.getConfiguration();
		
        //xml解析驱动
        final XMLLanguageDriver languageDriver = new XMLLanguageDriver();
        SqlSource sqlSource = languageDriver.createSqlSource(configuration,
        		 "<script>" + sql + "</script>", null);
        
        MappedStatement.Builder mapper = new MappedStatement.Builder(configuration, 
        		"update", sqlSource, SqlCommandType.UPDATE);
        
        ResultMap.Builder builder1 = new ResultMap.Builder(configuration, "update.resultMap", Integer.class, new ArrayList<>());
        mapper.resultMaps(Collections.singletonList(builder1.build()));
        
        ParameterMap.Builder builder2 = new ParameterMap.Builder(configuration,  "update.param", HashMap.class, new ArrayList<>());
        mapper.parameterMap(builder2.build());
        configuration.addMappedStatement(mapper.build());
        SqlSession sqlSession = null;
        try{
			sqlSession = sqlSessionFactory.openSession(true);
			return sqlSession.update("update", params);
        }finally{
        	if(sqlSession!=null) {
        		sqlSession.close();
        	}
        }
	}
	
	public Integer delete(Long dataSourceId,String sql,Map params) throws  DsException {
		
		
		SqlSessionFactory sqlSessionFactory = getSqlSessionFactory(dataSourceId);
		
		Configuration configuration = sqlSessionFactory.getConfiguration();
		
        //xml解析驱动
        final XMLLanguageDriver languageDriver = new XMLLanguageDriver();
        SqlSource sqlSource = languageDriver.createSqlSource(configuration,
        		 "<script>" + sql + "</script>", null);
        
        MappedStatement.Builder mapper = new MappedStatement.Builder(configuration, 
        		"delete", sqlSource, SqlCommandType.DELETE);
        
        ResultMap.Builder builder1 = new ResultMap.Builder(configuration, "delete.resultMap", Integer.class, new ArrayList<>());
        mapper.resultMaps(Collections.singletonList(builder1.build()));
        
        ParameterMap.Builder builder2 = new ParameterMap.Builder(configuration,  "delete.param", HashMap.class, new ArrayList<>());
        mapper.parameterMap(builder2.build());
        configuration.addMappedStatement(mapper.build());
        SqlSession sqlSession = null;
        try{
			sqlSession = sqlSessionFactory.openSession(true);
			return sqlSession.delete("delete", params);
        }finally{
        	if(sqlSession!=null) {
        		sqlSession.close();
        	}
        }
	}
	
	public <T> List<T> selectList(Long dataSourceId,String sql,Map params,Class<T> requiredType) throws  DsException {
		
		
		SqlSessionFactory sqlSessionFactory = getSqlSessionFactory(dataSourceId);
		
		Configuration configuration = sqlSessionFactory.getConfiguration();
		
        //xml解析驱动
        final XMLLanguageDriver languageDriver = new XMLLanguageDriver();
        SqlSource sqlSource = languageDriver.createSqlSource(configuration,
        		 "<script>" + sql + "</script>", null);
        
        MappedStatement.Builder mapper = new MappedStatement.Builder(configuration, 
        		"select", sqlSource, SqlCommandType.SELECT);
        
        ResultMap.Builder builder1 = new ResultMap.Builder(configuration, "select.resultMap", requiredType, new ArrayList<>());
        mapper.resultMaps(Collections.singletonList(builder1.build()));
        
        ParameterMap.Builder builder2 = new ParameterMap.Builder(configuration,  "select.param", HashMap.class, new ArrayList<>());
        mapper.parameterMap(builder2.build());
        configuration.addMappedStatement(mapper.build());
        SqlSession sqlSession = null;
        try{
			sqlSession = sqlSessionFactory.openSession(true);
			return sqlSession.selectList("select", params);
        }finally{
        	if(sqlSession!=null) {
        		sqlSession.close();
        	}
        }
	}
	
	
	
	
}
